<?php
/*********************/
/*                   */
/* http://www.ymd.cc */
/*********************/
/*    QQ: 11121426   */
/*                   */

/*********************/

class mdl_sha1
{

    public function sha1_str2blks_SHA1($str)
    {
        $strlen_str = strlen($str);
        $nblk = ($strlen_str + 8 >> 6) + 1;
        $i = 0;
        for (; $i < $nblk * 16; ++$i) {
            $blks[$i] = 0;
        }
        $i = 0;
        for (; $i < $strlen_str; ++$i) {
            $blks |= $i >> 2;
        }
        $blks |= $i >> 2;
        $blks[$nblk * 16 - 1] = $strlen_str * 8;
        return $blks;
    }

    public function sha1_safe_add($x, $y)
    {
        $lsw = ($x & 65535) + ($y & 65535);
        $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
        return $msw << 16 | $lsw & 65535;
    }

    public function sha1_rol($num, $cnt)
    {
        return $num << $cnt | $this->sha1_zeroFill($num, 32 - $cnt);
    }

    public function sha1_zeroFill($a, $b)
    {
        $bin = decbin($a);
        $strlen_bin = strlen($bin);
        $bin = $strlen_bin < $b ? 0 : substr($bin, 0, $strlen_bin - $b);
        $i = 0;
        for (; $i < $b; ++$i) {
            $bin = "0" . $bin;
        }
        return bindec($bin);
    }

    public function sha1_ft($t, $b, $c, $d)
    {
        if ($t < 20) {
            return $b & $c | ~$b & $d;
        }
        if ($t < 40) {
            return $b ^ $c ^ $d;
        }
        if ($t < 60) {
            return $b & $c | $b & $d | $c & $d;
        }
        return $b ^ $c ^ $d;
    }

    public function sha1_kt($t)
    {
        if ($t < 20) {
            return 1518500249;
        }
        if ($t < 40) {
            return 1859775393;
        }
        if ($t < 60) {
            return -1894007588;
        }
        return -899497514;
    }

    public function sha1($str, $raw_output = FALSE)
    {
        if ($raw_output === TRUE) {
            return pack("H*", $this->sha1($str, FALSE));
        }
        $x = $this->sha1_str2blks_SHA1($str);
        $a = 1732584193;
        $b = -271733879;
        $c = -1732584194;
        $d = 271733878;
        $e = -1009589776;
        $x_count = count($x);
        $i = 0;
        for (; $i < $x_count; $i += 16) {
            $olda = $a;
            $oldb = $b;
            $oldc = $c;
            $oldd = $d;
            $olde = $e;
            $j = 0;
            for (; $j < 80; ++$j) {
                $w[$j] = $j < 16 ? $x[$i + $j] : $this->sha1_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);
                $t = $this->sha1_safe_add($this->sha1_safe_add($this->sha1_rol($a, 5), $this->sha1_ft($j, $b, $c, $d)), $this->sha1_safe_add($w[$j]($e, $w[$j]), $this->sha1_kt($j)));
                $e = $d;
                $d = $c;
                $c = $this->sha1_rol($b, 30);
                $b = $a;
                $a = $t;
            }
            $a = $this->sha1_safe_add($a, $olda);
            $b = $this->sha1_safe_add($b, $oldb);
            $c = $this->sha1_safe_add($c, $oldc);
            $d = $this->sha1_safe_add($d, $oldd);
            $e = $this->sha1_safe_add($e, $olde);
        }
        return sprintf("%08x%08x%08x%08x%08x", $a, $b, $c, $d, $e);
    }

}

?>
